package net.shopxx.dao.impl;

import java.util.Calendar;
import java.util.Date;

import javax.persistence.EntityManager;
import javax.persistence.FlushModeType;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Repository;

import net.shopxx.constant.AccountsConstant;
import net.shopxx.dao.AccountsDao;
import net.shopxx.entity.AccountsItem;
import net.shopxx.pager.AccountsPageable;
import net.shopxx.pager.Page;

@Repository("accountsDaoImpl")
public class AccountsDaoImpl extends BaseDaoImpl<AccountsItem, Long>implements AccountsDao {

	@PersistenceContext
	protected EntityManager entityManager;

	public Long countByTbUserName(String userName, Date beginDate, Date endDate) {

		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<AccountsItem> criteriaQuery = criteriaBuilder.createQuery(AccountsItem.class);
		Root<AccountsItem> root = criteriaQuery.from(AccountsItem.class);
		criteriaQuery.select(root);
		Predicate restrictions = criteriaBuilder.conjunction();

		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("userName"), userName));

		if (beginDate != null) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.greaterThanOrEqualTo(root.<Date> get("orderTime"), beginDate));
		}
		if (endDate != null) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.lessThanOrEqualTo(root.<Date> get("orderTime"), endDate));
		}
		criteriaQuery.where(restrictions);

		return super.count(criteriaQuery, null);
	}

	@Override
	public Long countByOrderTbId(Long orderId) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<AccountsItem> criteriaQuery = criteriaBuilder.createQuery(AccountsItem.class);
		Root<AccountsItem> root = criteriaQuery.from(AccountsItem.class);
		criteriaQuery.select(root);
		Predicate restrictions = criteriaBuilder.conjunction();

		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("orderId"), orderId));

		criteriaQuery.where(restrictions);

		return super.count(criteriaQuery, null);
	}

	@Override
	public Page<AccountsItem> findStatsPage(AccountsPageable pageable) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<AccountsItem> criteriaQuery = criteriaBuilder.createQuery(AccountsItem.class);
		Root<AccountsItem> root = criteriaQuery.from(AccountsItem.class);
		criteriaQuery.select(root);
		Predicate restrictions = criteriaBuilder.conjunction();

		if (StringUtils.isNotBlank(pageable.getStoreId())) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("storeId"), pageable.getStoreId()));
		}
		if(StringUtils.isNotBlank(pageable.getOrderStatus())){
			if (Integer.valueOf(pageable.getOrderStatus()) == AccountsConstant.TB_ORDER_STATUS_NORMAL) {
				restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("status"), AccountsConstant.TB_ORDER_STATUS_NORMAL));
			} else {
				restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.notEqual(root.get("status"), AccountsConstant.TB_ORDER_STATUS_NORMAL));
			}
		}
		if (StringUtils.isNotBlank(pageable.getOperator())) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("operator"), pageable.getOperator()));
		}
		if (pageable.getBeginDate() != null) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.greaterThanOrEqualTo(root.<Date> get("orderTime"), pageable.getBeginDate()));
		}
		if (pageable.getEndDate() != null) {
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(pageable.getEndDate());
			calendar.add(Calendar.DAY_OF_MONTH, 1);
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.lessThanOrEqualTo(root.<Date> get("orderTime"), calendar.getTime()));
		}
		// 统计只计算正常订单，不统计刷单订单
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("type"), AccountsConstant.ANALYZED_ORDER_TYPE_TB));
		criteriaQuery.where(restrictions);

		return findPage(criteriaQuery, pageable);
	}

	@Override
	public Float findStatsSum(AccountsPageable pageable) {

		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Float> criteriaQuery = criteriaBuilder.createQuery(Float.class);
		Root<AccountsItem> root = criteriaQuery.from(AccountsItem.class);
		criteriaQuery.select(criteriaBuilder.sum(root.<Float> get("realPaidFee")));
		Predicate restrictions = criteriaBuilder.conjunction();

		if (StringUtils.isNotBlank(pageable.getStoreId())) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("storeId"), pageable.getStoreId()));
		}
		if(StringUtils.isNotBlank(pageable.getOrderStatus())){
			if (Integer.valueOf(pageable.getOrderStatus()) == AccountsConstant.TB_ORDER_STATUS_NORMAL) {
				restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("status"), AccountsConstant.TB_ORDER_STATUS_NORMAL));
			} else {
				restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.notEqual(root.get("status"), AccountsConstant.TB_ORDER_STATUS_NORMAL));
			}
		}
		if (StringUtils.isNotBlank(pageable.getOperator())) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("operator"), pageable.getOperator()));
		}
		if (pageable.getBeginDate() != null) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.greaterThanOrEqualTo(root.<Date> get("orderTime"), pageable.getBeginDate()));
		}
		if (pageable.getEndDate() != null) {
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(pageable.getEndDate());
			calendar.add(Calendar.DAY_OF_MONTH, 1);
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.lessThanOrEqualTo(root.<Date> get("orderTime"), calendar.getTime()));
		}
		// 统计只计算正常订单，不统计刷单订单
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("type"), AccountsConstant.ANALYZED_ORDER_TYPE_TB));
		criteriaQuery.where(restrictions);
		return entityManager.createQuery(criteriaQuery).setFlushMode(FlushModeType.COMMIT).getSingleResult();
	}

	@Override
	public Long findStatsCount(AccountsPageable pageable) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<AccountsItem> criteriaQuery = criteriaBuilder.createQuery(AccountsItem.class);
		Root<AccountsItem> root = criteriaQuery.from(AccountsItem.class);
		criteriaQuery.select(root);
		Predicate restrictions = criteriaBuilder.conjunction();

		if (StringUtils.isNotBlank(pageable.getStoreId())) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("storeId"), pageable.getStoreId()));
		}
		if(StringUtils.isNotBlank(pageable.getOrderStatus())){
			if (Integer.valueOf(pageable.getOrderStatus()) == AccountsConstant.TB_ORDER_STATUS_NORMAL) {
				restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("status"), AccountsConstant.TB_ORDER_STATUS_NORMAL));
			} else {
				restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.notEqual(root.get("status"), AccountsConstant.TB_ORDER_STATUS_NORMAL));
			}
		}
		if (StringUtils.isNotBlank(pageable.getOperator())) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("operator"), pageable.getOperator()));
		}
		if (pageable.getBeginDate() != null) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.greaterThanOrEqualTo(root.<Date> get("orderTime"), pageable.getBeginDate()));
		}
		if (pageable.getEndDate() != null) {
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(pageable.getEndDate());
			calendar.add(Calendar.DAY_OF_MONTH, 1);
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.lessThanOrEqualTo(root.<Date> get("orderTime"), calendar.getTime()));
		}
		// 统计只计算正常订单，不统计刷单订单
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("type"), AccountsConstant.ANALYZED_ORDER_TYPE_TB));
		criteriaQuery.where(restrictions);
		return super.count(criteriaQuery, null);
	}

}
